package com.yz.xyt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yz.xyt.constant.Constants;
import com.yz.xyt.constant.HttpStatus;
import com.yz.xyt.domain.Leave;
import com.yz.xyt.domain.LeaveRule;
import com.yz.xyt.domain.ResponseResult;
import com.yz.xyt.domain.vo.LeaveVo;
import com.yz.xyt.mapper.LeaveMapper;
import com.yz.xyt.mapper.LeaveRuleMapper;
import com.yz.xyt.service.ILeaveService;
import com.yz.xyt.utils.DateUtils;
import com.yz.xyt.utils.HmacUtils;
import com.yz.xyt.utils.HttpUtils;
import com.yz.xyt.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

/**
 * 请假Service
 * @author JW.WANG
 */
@Service
public class LeaveServiceImpl implements ILeaveService {

    @Autowired
    LeaveMapper leaveMapper;

    @Autowired
    LeaveRuleMapper leaveRuleMapper;

    /**
     * 收紧时长
     */
    @Value("${xyt.shrink}")
    private Long shrinkTime;

    /**
     * 常态时长
     */
    @Value("${xyt.normal}")
    private Long normalTime;

    /**
     * 门禁密钥
     */
    @Value("${card.secret}")
    private String cardSecret;

    /**
     * 门禁添加请假路径
     */
    @Value("${card.addLeaveUrl}")
    private String addLeaveUrl;
    /**
     * 门禁销假路径
     */
    @Value("${card.eliminateLeaveUrl}")
    private String eliminateLeaveUrl;

    @Override
    public int deleteByPrimaryKey(Integer id) {
        return leaveMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Leave record) {
        return leaveMapper.insert(record);
    }

    @Override
    public int insertSelective(Leave record) {
        return leaveMapper.insertSelective(record);
    }

    @Override
    public Leave selectByPrimaryKey(Integer id) {
        return leaveMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Leave record) {
        return leaveMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Leave record) {
        return leaveMapper.updateByPrimaryKey(record);
    }

    /**
     * 通过学号查询是否正在请假
     * @param studentNumber
     * @return
     */
    @Override
    public Boolean selectInLeaveByStudentNumber(Integer studentNumber) {
        List<Leave> leaveList = leaveMapper.selectInLeaveByStudentNumber(studentNumber);
        if(leaveList.size() > 0){
            return true;
        }
        return false;
    }

    /**
     * 通过学号查询异常请假
     * @param studentNumber
     * @return
     */
    @Override
    public Boolean selectErrorLeaveByStudentNumber(Integer studentNumber) {
        List<Leave> leaveList = leaveMapper.selectErrorLeaveByStudentNumber(studentNumber);
        if(leaveList.size() > 0){
            return true;
        }
        return false;
    }

    /**
     * 报备请假
     * @param leave
     * @return
     */
    @Transactional
    @Override
    public ResponseResult reportLeave(Leave leave) {

        ResponseResult result = new ResponseResult();

        Date startTime = leave.getStartTime();
        Date endTime = leave.getEndTime();

        //最早时间限制
        Date minTime =  DateUtils.parseDate(DateUtils.getDate() + " 07:00:00");

        //请假日期不能跨越当天8点
        Date maxTime = DateUtils.parseDate(DateUtils.getDate() + " 19:59:59");

        if (!DateUtils.isSameSystemDay(startTime)){
            result.setCode(HttpStatus.APPLY_LEAVE_FAILED);
            result.setMsg("请假时间仅限当日早七点到晚八点之间");
            return result;
        }

        boolean isSameDay = DateUtils.isSameDay(startTime, endTime);
        if (!isSameDay){
            result.setCode(HttpStatus.APPLY_LEAVE_FAILED);
            result.setMsg("请假时间不能跨越当天");
            return  result;
        }

        if(startTime.before(minTime)){
            result.setMsg("早上七点以前不能报备请假");
            result.setCode(HttpStatus.ERROR);
            return result;
        }

        if (endTime.after(maxTime)){
            result.setCode(HttpStatus.APPLY_LEAVE_FAILED);
            result.setMsg("晚上八点以后不能报备请假");
            return  result;
        }

        //计算时长
        Long timeLength = DateUtils.getDifferenceHour(endTime,startTime);

        //获取报备请假当前使用规则
        LeaveRule leaveRule = leaveRuleMapper.selectIsUseRule();
        String ruleNumber = leaveRule.getRuleNumber();
        //验证请假时长

        if(Constants.RULE_NUMBER_SHRINK.equals(ruleNumber)){
            //收紧状态验证时长2小时
            if(timeLength.longValue() > shrinkTime.longValue()){
                result.setCode(HttpStatus.APPLY_LEAVE_FAILED);
                result.setMsg("请假时间不能超2小时");
                return  result;
            }

        }
        if (Constants.RULE_NUMBER_NORMAL.equals(ruleNumber)){
            //常态验证时长4小时
            if(timeLength.longValue() > normalTime.longValue()){
                result.setCode(HttpStatus.APPLY_LEAVE_FAILED);
                result.setMsg("请假时间不能超4小时");
                return  result;
            }
        }

        //保存请假信息
        leave.setCreateBy(SecurityUtils.getUsername());
        leave.setCreateDate(DateUtils.getNowDate());
        System.out.println("************");
        System.out.println(leave);
        System.out.println("************");
        leaveMapper.insert(leave);
        //自动审批
        approvalEnd(leave,Constants.AUTO_APPROVAL_TYPE);

        result.setCode(HttpStatus.SUCCESS);
        result.setMsg("请假成功");

        return result;
    }

    /**
     * 常规请假
     * @param leave
     * @return
     */
    @Transactional
    @Override
    public ResponseResult normalLeave(Leave leave) {
        ResponseResult result = new ResponseResult();
        //请假时间
        Date endTime = leave.getEndTime();
        Date startTime = leave.getStartTime();

        //设置时长和级别对应
        Long differenceDay = DateUtils.getDifferenceDay(endTime,startTime);
        boolean isSameDay = DateUtils.isSameDay(startTime, endTime);

        if (isSameDay){
            leave.setLevel(Constants.LEAVE_LEVEL_1);
        }else{
            if (differenceDay <10){
                leave.setLevel(Constants.LEAVE_LEVEL_2);
            }
            if(differenceDay >=10 && differenceDay <30){
                leave.setLevel(Constants.LEAVE_LEVEL_3);
            }
            if(differenceDay >=30){
                leave.setLevel(Constants.LEAVE_LEVEL_4);
            }
        }

        //设置请假为待审核状态
        leave.setStatus(Constants.APPROVAL_WAIT);
        //设置请假审核流程为辅导员审核
        leave.setApprovalStatus(Constants.APPROVAL_STATUS_FD);

        leave.setCreateBy(SecurityUtils.getUsername());
        leave.setCreateDate(DateUtils.getNowDate());
        leaveMapper.insertSelective(leave);

        result.setCode(HttpStatus.SUCCESS);
        result.setMsg("请假成功");

        return result;
    }

    /**
     * 辅导员审批
     * @param leave
     */
    @Transactional
    @Override
    public void instructorApproval(Leave leave) {
        //获取请假等级
        String level = getLevel(leave.getId());

        //等级一级，辅导员审批则流程结束,其他等级设置流程等级为书记审批
        if(level.equals(Constants.LEAVE_LEVEL_1)){
            //设置审批状态结束
            Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(leave.getId()));
            record.setApprovalStatus(Constants.APPROVAL_STATUS_END);
            //审批结束
            approvalEnd(record,"");
        }else{
            //流程步骤设置为书记
            leave.setApprovalStatus(Constants.APPROVAL_STATUS_SJ);
            //将请假状态设置为审批中
            leave.setStatus(Constants.APPROVAL_IN);
            leave.setUpdateBy(SecurityUtils.getUsername());
            leave.setUpdateDate(DateUtils.getNowDate());
            leaveMapper.updateByPrimaryKeySelective(leave);
        }
    }

    /**
     * 书记审批
     * @param leave
     */
    @Transactional
    @Override
    public void secretaryApproval(Leave leave) {
        //获取请假等级
        String level = getLevel(leave.getId());
        //等级二级，书记审批则流程结束,其他等级设置流程等级为学生处审批
        if(level.equals(Constants.LEAVE_LEVEL_2)){
            //设置审批状态结束
            Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(leave.getId()));
            record.setApprovalStatus(Constants.APPROVAL_STATUS_END);
            //审批结束
            approvalEnd(record,"");
        }else{
            //流程步骤设置为学生处
            leave.setApprovalStatus(Constants.APPROVAL_STATUS_XSC);
            //将请假状态设置为审批中
            leave.setStatus(Constants.APPROVAL_IN);
            leave.setUpdateBy(SecurityUtils.getUsername());
            leave.setUpdateDate(DateUtils.getNowDate());
            leaveMapper.updateByPrimaryKeySelective(leave);
        }
    }

    /**
     * 学生处审批
     * @param leave
     */
    @Transactional
    @Override
    public void studentOfficeApproval(Leave leave) {
        //获取请假等级
        String level = getLevel(leave.getId());
        //等级三级，学生处审批则流程结束,其他等级设置流程等级为分管领导审批
        if(level.equals(Constants.LEAVE_LEVEL_3)){
            //设置审批状态结束
            Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(leave.getId()));
            record.setApprovalStatus(Constants.APPROVAL_STATUS_END);
            //审批结束
            approvalEnd(record,"");
        }else{
            //流程步骤设置为分管领导
            leave.setApprovalStatus(Constants.APPROVAL_STATUS_FGLD);
            //将请假状态设置为审批中
            leave.setStatus(Constants.APPROVAL_IN);
            leave.setUpdateBy(SecurityUtils.getUsername());
            leave.setUpdateDate(DateUtils.getNowDate());
            leaveMapper.updateByPrimaryKeySelective(leave);
        }
    }

    /**
     * 分管领导审批
     * @param leave
     */
    @Transactional
    @Override
    public void leaderApproval(Leave leave) {
        //设置审批状态结束
        Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(leave.getId()));
        record.setApprovalStatus(Constants.APPROVAL_STATUS_END);
        //审批结束
        approvalEnd(record,"");
    }

    /**
     * 驳回请假
     * @param leave
     */
    @Transactional
    @Override
    public void rejectApply(Leave leave) {
        //设置请假状态为驳回
        leave.setStatus(Constants.APPROVAL_REJECT);
        leave.setApprovalStatus(Constants.APPROVAL_STATUS_END);
        leave.setUpdateBy(SecurityUtils.getUsername());
        leave.setUpdateDate(DateUtils.getNowDate());
        leaveMapper.updateByPrimaryKeySelective(leave);
    }

    /**
     * 审批结束
     * @param leave
     * @param approvalType 审批标识
     */
    @Transactional
    @Override
    public void approvalEnd(Leave leave,String approvalType) {
        //设置请假状态为请假中
        leave.setStatus(Constants.LEAVE_IN);
        if(Constants.AUTO_APPROVAL_TYPE.equals(approvalType)){
            leave.setUpdateBy("system");
        }else{
            leave.setUpdateBy(SecurityUtils.getUsername());
        }

        leave.setUpdateDate(DateUtils.getNowDate());
        leaveMapper.updateByPrimaryKeySelective(leave);
        addCardLeaveInfo(leave);
    }

    /**
     * 查询所有 未审批和审批中 且 无异常 的请假信息
     * @return
     */
    @Override
    public List<Leave> timeoutNotApproval() {
        return leaveMapper.timeoutNotApproval();
    }

    @Override
    public List<Leave> timeoutNotLeave() {
        return leaveMapper.timeoutNotLeave();
    }

    /**
     * 请假撤销
     * @param leave
     */
    @Transactional
    @Override
    public int cancelLeave(Leave leave) {
        Leave cancelLeave = new Leave();
        cancelLeave.setId(leave.getId());
        cancelLeave.setUpdateBy(SecurityUtils.getUsername());
        cancelLeave.setUpdateDate(DateUtils.getNowDate());
        cancelLeave.setStatus(Constants.APPLY_RECALL);
        cancelLeave.setApprovalStatus(Constants.APPROVAL_STATUS_END);
        return leaveMapper.updateByPrimaryKeySelective(cancelLeave);
    }

    /**
     * 启用报备请假规则
     * @param ruleId
     */
    @Transactional
    @Override
    public void startLeaveRule(Integer ruleId) {
        LeaveRule rule = new LeaveRule();
        rule.setStatus(Constants.REPORT_LEAVE_STOP);
        //先停用所有规则
        rule.setUpdateBy(SecurityUtils.getUsername());
        rule.setUpdateDate(DateUtils.getNowDate());
        leaveRuleMapper.stopAll(rule);
        //启用当前选择的规则
        rule.setStatus(Constants.REPORT_LEAVE_START);
        rule.setId(ruleId);
        leaveRuleMapper.startRule(rule);
    }

    /**
     * 停用报备请假规则
     * @param ruleId
     */
    @Transactional
    @Override
    public void stopLeaveRule(Integer ruleId) {
        LeaveRule rule = new LeaveRule();
        rule.setStatus(Constants.REPORT_LEAVE_STOP);
        rule.setId(ruleId);
        leaveRuleMapper.updateByPrimaryKeySelective(rule);
    }

    /**
     * 辅导员查询请假列表
     * @return
     */
    @Override
    public List<LeaveVo> selectByFdy(LeaveVo leave) {
        return leaveMapper.selectByFdy(leave);
    }

    /**
     * 书记查询请假列表
     * @param leave
     * @return
     */
    @Override
    public List<LeaveVo> selectBySj(LeaveVo leave) {
        return leaveMapper.selectBySj(leave);
    }

    /**
     * 学生处查询请假列表
     * @param leave
     * @return
     */
    @Override
    public List<LeaveVo> selectByXsc(LeaveVo leave) {
        return leaveMapper.selectByXsc(leave);
    }

    /**
     * 分管领导查询请假列表
     * @param leave
     * @return
     */
    @Override
    public List<LeaveVo> selectByFgld(LeaveVo leave) {
        return leaveMapper.selectByFgld(leave);
    }

    /**
     * 学生查询请假列表
     * @param leaveVo
     * @return
     */
    @Override
    public List<LeaveVo> selectByStudent(LeaveVo leaveVo) {
        return leaveMapper.selectByStudent(leaveVo);
    }

    /**
     * 分页查询请假
     * @param leaveVo
     * @return
     */
    @Override
    public PageInfo queryForPage(LeaveVo leaveVo) {

        boolean appUser = SecurityUtils.getLoginUser().isAppUser();

        PageHelper.startPage(leaveVo.getPageNumber(),leaveVo.getPageSize());

        List<LeaveVo> list = new ArrayList<>();
        List<String> roles = SecurityUtils.getLoginUser().getRoles();
        //学生查询
        if (roles.contains(Constants.ROLE_STUDENT)){
            leaveVo.setStudentNumber(SecurityUtils.getUsername());
            list = selectByStudent(leaveVo);
        }

        //辅导员查询
        if (roles.contains(Constants.APPROVAL_ROLE_FD)){
            leaveVo.setStaffNumber(SecurityUtils.getUsername());
            list = selectByFdy(leaveVo);
            list.stream().forEach(s->{
                //当请假撤销时，设置审批状态为false
                if (s.getLeaveCancel()){
                    s.setApproval(false);
                }
            });
        }
        //书记查询
        if(roles.contains(Constants.APPROVAL_ROLE_SJ)){
            leaveVo.setStaffNumber(SecurityUtils.getUsername());
            if (appUser){
                leaveVo.setApprovalStatus(Constants.APPROVAL_STATUS_SJ);
                leaveVo.setStatus(Constants.APPROVAL_IN);
            }
            list = selectBySj(leaveVo);
        }
        //学生处查询
        if(roles.contains(Constants.APPROVAL_ROLE_XSC)){
            if (appUser){
                leaveVo.setApprovalStatus(Constants.APPROVAL_STATUS_XSC);
                leaveVo.setStatus(Constants.APPROVAL_IN);
            }
            list = selectByXsc(leaveVo);
        }
        //分管领导查询
        if(roles.contains(Constants.APPROVAL_ROLE_FGLD)){
            leaveVo.setStaffNumber(SecurityUtils.getUsername());
            if (appUser){
                leaveVo.setApprovalStatus(Constants.APPROVAL_STATUS_FGLD);
                leaveVo.setStatus(Constants.APPROVAL_IN);
            }
            list = selectByFgld(leaveVo);
        }
        list.stream().forEach(l->{
            if(l.getLeaveType().equals(Constants.LEAVE_TYPE_SJ)){
                l.setLeaveType(Constants.TRANSLATE_LEAVE_TYPE_SJ);
            }
            if(l.getLeaveType().equals(Constants.LEAVE_TYPE_REPORT)){
                l.setLeaveType(Constants.TRANSLATE_LEAVE_TYPE_REPORT);
            }
            if(l.getLeaveType().equals(Constants.LEAVE_TYPE_BJ)){
                l.setLeaveType(Constants.TRANSLATE_LEAVE_TYPE_BJ);
            }
            if(l.getLeaveType().equals(Constants.LEAVE_TYPE_JR)){
                l.setLeaveType(Constants.TRANSLATE_LEAVE_TYPE_JR);
            }
            if (l.getLeaveType().equals(Constants.LEAVE_TYPE_OTHER)){
                l.setLeaveType(Constants.TRANSLATE_LEAVE_TYPE_OTHER);
            }

            if (l.getStatus().equals(Constants.APPROVAL_WAIT)){
                l.setStatus(Constants.LEAVE_STATUS_DSP);
            }
            if(l.getStatus().equals(Constants.APPROVAL_IN)){
                l.setStatus(Constants.LEAVE_STATUS_SPZ);
            }
            if(l.getStatus().equals(Constants.APPROVAL_REJECT)){
                l.setStatus(Constants.LEAVE_STATUS_JJ);
            }
            if(l.getStatus().equals(Constants.APPLY_RECALL)){
                l.setStatus(Constants.LEAVE_STATUS_CX);
            }
            if(l.getStatus().equals(Constants.LEAVE_IN)){
                l.setStatus(Constants.LEAVE_STATUS_QJZ);
            }
            if(l.getStatus().equals(Constants.LEAVE_CANCEL)){
                l.setStatus(Constants.LEAVE_STATUS_YXJ);
            }
            if(l.getStatus().equals(Constants.LEAVE_TIME_OUT_NOT_APPROVAL)){
                l.setStatus(Constants.LEAVE_STATUS_CSWSP);
            }
            if(l.getStatus().equals(Constants.LEAVE_TIME_OUT_NOT_CANCEL)){
                l.setStatus(Constants.LEAVE_STATUS_CSWXJ);
            }
        });
        return new PageInfo(list);
    }



    /**
     * 获取请假级别
     * @param id
     * @return
     */
    private String getLevel(Integer id){
        return leaveMapper.selectByPrimaryKey(id).getLevel();
    }

    /**
     * 辅导员 处理 超时未销假
     * @param  leave  携带假单id
     * @return
     */
    @Transactional
    @Override
    public ResponseResult dealLeaveTimeOutNotCancel(Leave leave) {
        ResponseResult result = new ResponseResult();

        // 通过 假单id 更新数据
        // 将status改为 5 请假中
        leave.setStatus(Constants.LEAVE_IN);
        // 将 endTime 以当前时间 延长10分钟
        Date afterTime = DateUtils.afterTime(10);
        leave.setEndTime(afterTime);
        leave.setUpdateBy(SecurityUtils.getUsername());
        leave.setUpdateDate(DateUtils.getNowDate());

        int i = leaveMapper.updateByPrimaryKeySelective(leave);
        if (i > 0){
            result.setCode(HttpStatus.SUCCESS);
            result.setMsg("状态更新成功");
            result.setData(i);
        }else {
            result.setCode(HttpStatus.ERROR);
            result.setMsg("状态更新失败");
            result.setData(i);
        }

        return result;
    }

    /**
     * 销假
     * @param leave
     * @return
     */
    @Transactional
    @Override
    public int expendedLeave(Leave leave) {
        leave.setStatus(Constants.LEAVE_CANCEL);
        leave.setUpdateBy(SecurityUtils.getUsername());
        leave.setUpdateDate(DateUtils.getNowDate());
        eliminateCardLeave(leave);
        int count = leaveMapper.updateByPrimaryKeySelective(leave);
        return count;
    }

    /**
     * 批量审批
     * @param idList
     * @return
     */
    @Transactional
    @Override
    public ResponseResult batchAgree(List<String> idList) {

        ResponseResult result = new ResponseResult();
        result.setMsg("批量审核成功");
        result.setCode(HttpStatus.SUCCESS);

        //获取当前用户角色
        List<String> userRoles = SecurityUtils.getLoginUser().getRoles();
        List<String> approvalIds = new ArrayList<>();
        if(userRoles.contains(Constants.APPROVAL_ROLE_SJ)){
            idList.stream().forEach(id->{
                Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(id));
                if (record.getApprovalStatus().equals(Constants.APPROVAL_STATUS_SJ)){
                    approvalIds.add(id);
                }
            });
            if (approvalIds.size() == 0){
                result.setMsg("审核失败,不能重复审核");
                result.setCode(HttpStatus.APPROVAL_LEAVE_FAILED);
                return result;
            }
            //书记审核
            approvalIds.stream().forEach(s -> {
                secretaryApproval(leaveMapper.selectByPrimaryKey(Integer.valueOf(s)));
            });
        }else if (userRoles.contains(Constants.APPROVAL_ROLE_XSC)){
            idList.stream().forEach(id->{
                Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(id));
                if (record.getApprovalStatus().equals(Constants.APPROVAL_STATUS_XSC)){
                    approvalIds.add(id);
                }
            });
            if (approvalIds.size() == 0){
                result.setMsg("审核失败,不能重复审核");
                result.setCode(HttpStatus.APPROVAL_LEAVE_FAILED);
                return result;
            }
            //学生处审核
            approvalIds.stream().forEach(s -> {
                studentOfficeApproval(leaveMapper.selectByPrimaryKey(Integer.valueOf(s)));
            });
        }else if(userRoles.contains(Constants.APPROVAL_ROLE_FGLD)){
            idList.stream().forEach(id->{
                Leave record = leaveMapper.selectByPrimaryKey(Integer.valueOf(id));
                if (record.getApprovalStatus().equals(Constants.APPROVAL_STATUS_FGLD)){
                    approvalIds.add(id);
                }
            });
            if (approvalIds.size() == 0){
                result.setMsg("审核失败,不能重复审核");
                result.setCode(HttpStatus.APPROVAL_LEAVE_FAILED);
                return result;
            }
            //分管领导审核
            approvalIds.stream().forEach(s -> {
                leaderApproval(leaveMapper.selectByPrimaryKey(Integer.valueOf(s)));
            });
        }else {
            result.setMsg("审核失败");
            result.setCode(HttpStatus.APPROVAL_LEAVE_FAILED);
        }

        return result;
    }

    /**
     * 门禁请假信息发送
     * @param leave
     */
    @Override
    public void addCardLeaveInfo(Leave leave) {
        //获取请假类型，报备请假默认为事假
        String leaveType = leave.getLeaveType();
        if(Constants.LEAVE_TYPE_REPORT.equals(leaveType)){
            leave.setLeaveType(Constants.LEAVE_TYPE_SJ);
        }
        sendCardRequest(leave,true);
    }

    /**
     * 门禁销假信息发送
     * @param leave
     */
    @Override
    public void eliminateCardLeave(Leave leave) {
        leave  = leaveMapper.selectByPrimaryKey(leave.getId());
        sendCardRequest(leave,false);
    }

    /**
     * 是否能拒绝判断
     * @param leave
     * @return
     */
    @Override
    public boolean isAllowReject(Leave leave) {
        boolean isAllow = true;

        //辅导员的拒绝操作，只能在请假处于待审批状态中
        List<String> roles = SecurityUtils.getLoginUser().getRoles();
        if (roles.contains(Constants.APPROVAL_ROLE_FD) &&
                !Constants.APPROVAL_STATUS_FD.equals(leave.getApprovalStatus())){
            isAllow = false;
        }
        if (roles.contains(Constants.APPROVAL_ROLE_SJ) &&
                !Constants.APPROVAL_STATUS_SJ.equals(leave.getApprovalStatus())){
            isAllow = false;
        }
        if (roles.contains(Constants.APPROVAL_ROLE_XSC) &&
                !Constants.APPROVAL_STATUS_XSC.equals(leave.getApprovalStatus())){
            isAllow = false;
        }
        if (roles.contains(Constants.APPROVAL_ROLE_FGLD) &&
                !Constants.APPROVAL_STATUS_FGLD.equals(leave.getApprovalStatus())){
            isAllow = false;
        }
        return isAllow;
    }

    /**
     *
     * 构建门禁请销假参数
     * @param leave
     * @param isAdd  true 请假 false 销假
     * @return
     */
    private void sendCardRequest(Leave leave,boolean isAdd){

        //当前系统时间戳
        long timestamp = getTimeStamp();

        String leaveType = leave.getLeaveType();
        //构建签名参数
        StringBuilder bl = new StringBuilder();

        if (isAdd){
            bl.append("enddate=")
                    .append(leave.getEndTime().getTime())
                    .append("&")
                    .append("leavetype=")
                    .append(Integer.valueOf(leaveType))
                    .append("&")
                    .append("reason=")
                    .append("ok")
                    .append("&")
                    .append("startdate=")
                    .append(leave.getStartTime().getTime())
                    .append("&")
                    .append("timestamp=")
                    .append(timestamp)
                    .append("&")
                    .append("userno=")
                    .append(leave.getStudentNumber());
        }else{
            bl.append("timestamp=")
                    .append(timestamp)
                    .append("&")
                    .append("userno=")
                    .append(leave.getStudentNumber());
        }

        //获取签名
        String sign = HmacUtils.encrypt(bl.toString(),cardSecret,HmacUtils.HMAC_SHA512).toUpperCase();
        //构建请假参数json串
        //参数顺序不能变
        Map<String,Object> map = new LinkedHashMap<>();
        if(isAdd){
            map.put("enddate",leave.getEndTime());
            map.put("leavetype",Integer.valueOf(leaveType));
            map.put("reason","ok");
            map.put("startdate",leave.getStartTime().getTime());
        }
        map.put("userno",leave.getStudentNumber());
        map.put("Sign",sign);
        map.put("Timestamp",timestamp);

        String requestParam = JSON.toJSONString(map);

        //循环三次排除网络故障
        int sendCount = 0;
        while(sendCount < 3){

            String response = null;
            if(isAdd){
                response = HttpUtils.sendPostRequest(requestParam,addLeaveUrl);
            }else{
                response = HttpUtils.sendPostRequest(requestParam,eliminateLeaveUrl);
            }

            JSONObject result = JSON.parseObject(response);
            if (Constants.CARD_RESULT_SUCCESS == result.getInteger("Status")){
                break;
            }
            sendCount = sendCount + 1;
        }
    }

    @Override
    public List<LeaveVo> getApprovedList(LeaveVo leaveVo) {
        return leaveMapper.selectApprovedList(leaveVo);
    }

    @Override
    public List<LeaveVo> selectApprovedListBySj(LeaveVo leaveVo){
        return leaveMapper.selectApprovedListBySj(leaveVo);
    }
    @Override
    public PageInfo queryApprovedLeaveForPage(LeaveVo leaveVo) {
        List<LeaveVo> list = new ArrayList<>();
        List<String> roles = SecurityUtils.getLoginUser().getRoles();

        if (roles.contains(Constants.APPROVAL_ROLE_FD)){
            return null;
        }
        if(roles.contains(Constants.APPROVAL_ROLE_SJ)){
            leaveVo.setApprovalStatus(Constants.APPROVAL_STATUS_SJ);
            leaveVo.setStatus("2");
            leaveVo.setStaffNumber(SecurityUtils.getUsername());
            list = leaveMapper.selectApprovedListBySj(leaveVo);
        }
        if(roles.contains(Constants.APPROVAL_ROLE_XSC)){
            leaveVo.setApprovalStatus(Constants.APPROVAL_STATUS_XSC);
            leaveVo.setStatus("2");
            list = leaveMapper.selectApprovedList(leaveVo);
        }

        return new PageInfo(list);
    }

    /**
     * 获取时间戳
     * @return
     */
    private long getTimeStamp(){
        String time = DateUtils.getTime();
        Date date = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, time);
        return date.getTime();
    }
}